/*
utf-8
------------------------------------------------
电子钟时序及功能控制程序
------------------------------------------------
由刘丙旭出品
遵循署名-非商业性使用-相同方式共享 4.0 国际协议 (CC BY-NC-SA 4.0)
详情访问https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh
------------------------------------------------
*/
`timescale 1ns/1ns
module clock_clock(
RESET,							//重置时钟为0
MODE,								//更改模式
SETBIT,							//更改校时位置
SET,								//校时按键，按下一次加一
clk,								//50MHz时钟输入
HH,								 	//时高位BCD
HL,								 	//时低位BCD
MH,									//分高位BCD
ML,									//分低位BCD
SH,									//秒高位BCD
SL,									//秒低位BCD
dp_in									//小数点
);

	input RESET,MODE,SETBIT,SET,clk;
	output HH,HL,MH,ML,SH,SL;
	output dp_in;
	
	wire clk_1Hz,clk1kHz;
	
	reg rst_H;
	
	wire SET_pulse;
	reg SET_tem1,SET_tem2;
	always @(posedge clk)
	begin
	SET_tem1 <= SET;
	SET_tem2 <= SET_tem1;
	end
	assign SET_pulse = ~SET_tem1 & (SET_tem2);
	
	
	/*
	reg MODE = 1;		//MODE为1时计时，0时校时
	always @(posedge MODE_ax)		//每按下一次mode，反转MODE信号
		MODE = ~MODE; 
	*/
		
	reg[3:0] SETBIT_loc = 4'b0000;
	reg[1:0] SETBIT_count = 0;
	always @(negedge SETBIT)
	begin
	if(SETBIT_count == 2'b11)
		SETBIT_count <= 0;
	else
		SETBIT_count <= SETBIT_count + 1;
	end
	always @(SETBIT_count)
	case(SETBIT_count)
		0:SETBIT_loc <= 4'b1000;	//HH校时
		1:SETBIT_loc <= 4'b0100;	//HL校时
		2:SETBIT_loc <= 4'b0010;	//MH校时
		3:SETBIT_loc <= 4'b0001;	//ML校时
		default SETBIT_loc <= 4'b0000;
	endcase
	
	reg[5:0] dp_in;
	always @(clk_1Hz) //闪烁显示小数点
	begin
	if(MODE & RESET)
		case(clk_1Hz)
			0:dp_in <= 6'b010101;
			1:dp_in <= 6'b000001;
		endcase
	else if(~MODE | ~RESET)
		dp_in <= 6'b010100; 
	end
	
	
	//当校时时，闪烁显示校时位置
	wire SET;
	reg SET_en;
	always @(clk_1Hz or SET)
	if(SET == 1'b1)
	begin
		if(~MODE)
		case(clk_1Hz)
			1'b0:SET_en <= 1'b0;
			1'b1:SET_en <= 1'b1;
		endcase
		else
			SET_en <= 1'b1;
	end
	else if(SET == 1'b0)
	begin
		SET_en <= 1'b1;
	end
	
	
	//SL
	wire t0;
	wire[3:0] SL;
	//assign t = (clk_1Hz & MODE);
	
	//MODE = 0时，不进行计时
	FF FF_0(
	.clk					(clk),
	.rst					(~RESET),
	.in						(clk_1Hz & MODE & RESET),
	.out_posedge	(t),
	.out_negedge	(),
	.out_pos_neg	()
	);
	
	timer timer_SL(
	.clk			(clk),	//时钟输入
	.RESET		(~RESET),		//重置信号输入
	.data			(4'd0),				//预置数(在这里要设置为0)
	.SET			(1'b0),				//置数端(上升沿置数，在这里要设置为0)
	.en				(1'b1),				//使能端(1使能，0输出4'b1111)
	.a				(4'd9),				//最高计数(最高为9)
	.mode			(MODE),				//计时、校时切换端(1计时，0校时)
	.c_in			(t),				//进位输入
	.data_out	(SL),				//一位BCD输出
	.c_out		(t0)					//进位输出
	);
	
	//SH
	wire t1;
	wire[3:0] SH;
	timer timer_SH(
	.clk			(clk),	//时钟输入
	.RESET		(~RESET),		//重置信号输入
	.data			(4'd0),				//预置数(在这里要设置为0)
	.SET			(1'b0),				//置数端(上升沿置数，在这里要设置为0)
	.en				(1'b1),				//使能端(1使能，0输出4'b1111)
	.a				(4'd5),				//最高计数(最高为9)
	.mode			(MODE),				//计时、校时切换端(1计时，0校时)
	.c_in			(t0),				//进位输入
	.data_out	(SH),				//一位BCD输出
	.c_out		(t1)					//进位输出
	);
	
	//ML
	wire t2;
	wire[3:0] ML;
	timer timer_ML(
	.clk			(clk),	//时钟输入
	.RESET		(~RESET),		//重置信号输入
	.data			(4'd0),				//预置数(在这里要设置为0)
	.SET			(1'b0),				//置数端(上升沿置数，在这里要设置为0)
	.en				(SET_en|~SETBIT_loc[0]),				//使能端(1使能，0输出4'b1111)
	.a				(4'd9),				//最高计数(最高为9)
	.mode			(MODE),				//计时、校时切换端(1计时，0校时)
	.c_in			(t1|(SET_pulse & SETBIT_loc[0] & ~MODE)),	//进位输入
	.data_out	(ML),				//一位BCD输出
	.c_out		(t2)					//进位输出
	);
	
	//MH
	wire t3;
	wire[3:0] MH;
	timer timer_MH(
	.clk			(clk),	//时钟输入
	.RESET		(~RESET),		//重置信号输入
	.data			(4'd0),				//预置数(在这里要设置为0)
	.SET			(1'b0),				//置数端(上升沿置数，在这里要设置为0)
	.en				(SET_en|~SETBIT_loc[1]),				//使能端(1使能，0输出4'b1111)
	.a				(4'd5),				//最高计数(最高为9)
	.mode			(MODE),				//计时、校时切换端(1计时，0校时)
	.c_in			(t2|(SET_pulse & SETBIT_loc[1] & ~MODE)),	//进位输入
	.data_out	(MH),				//一位BCD输出
	.c_out		(t3)					//进位输出
	);
	
	reg [3:0] HL_max;
	always @(posedge clk)
	begin
		if(HH == 4'd2)
			HL_max <= 4'd3;
		else
			HL_max <= 4'd9;
	end
	
	reg [3:0] HH_max;
	always @(posedge clk)
	begin
	if (MODE == 1'b0)
		begin
		if(HL >= 4'd4)
			HH_max <= 4'd1;
		else
			HH_max <= 4'd2;
		end
	else
		HH_max <= 4'd2;
	end
	
	//HL
	wire t4;
	wire[3:0] HL;
	timer timer_HL(
	.clk			(clk),	//时钟输入
	.RESET		((~RESET)|rst_H),		//重置信号输入
	.data			(4'd0),				//预置数(在这里要设置为0)
	.SET			(1'b0),				//置数端(上升沿置数，在这里要设置为0)
	.en				(SET_en|~SETBIT_loc[2]),				//使能端(1使能，0输出4'b1111)
	.a				(HL_max),				//最高计数(最高为9)
	.mode			(MODE),				//计时、校时切换端(1计时，0校时)
	.c_in			(t3|(SET_pulse & SETBIT_loc[2] & ~MODE)),	//进位输入
	.data_out	(HL),				//一位BCD输出
	.c_out		(t4)					//进位输出
	);
	
	//HH
	wire t5;
	wire[3:0] HH;
	timer timer_HH(
	.clk			(clk),	//时钟输入
	.RESET		((~RESET)|rst_H),		//重置信号输入
	.data			(4'd0),				//预置数(在这里要设置为0)
	.SET			(1'b0),				//置数端(上升沿置数，在这里要设置为0)
	.en				(SET_en|~SETBIT_loc[3]),				//使能端(1使能，0输出4'b1111)
	.a				(HH_max),				//最高计数(最高为9)
	.mode			(MODE),				//计时、校时切换端(1计时，0校时)
	.c_in			(t4|(SET_pulse & SETBIT_loc[3] & ~MODE)),	//进位输入
	.data_out	(HH),				//一位BCD输出
	.c_out		(t5)					//进位输出
	);
	
	
	clk_50MHz_1kHz clk_50MHz_1kHz
	(
	.clk_50MHz		(clk),
	.clk_1kHz			(clk_1kHz)
	);
	
	clk_1k_1Hz clk_1k_1Hz
	(
	.clk_1kHz			(clk_1kHz),
	.clk_1Hz			(clk_1Hz)
	);
	
	

	
	
endmodule